import _ from "lodash";

//指定长度和基数
export function _getUUID(len, radix) {
  var chars =
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
  var uuid = [],
    i;
  radix = radix || chars.length;
  if (len) {
    for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
  } else {
    var r;
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-";
    uuid[14] = "4";
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | (Math.random() * 16);
        uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
      }
    }
  }
  return uuid.join("");
}

/**
 *
 * @description 根据key值，返回当前链路的数据
 * @author 翟磊
 * @date 2020-03-06
 * @param {string} key - 目标值
 * @param {string} keyName - key名称
 * @param {[tree]} data - 树形数据
 * @return {[json]} 函数返回值:当前链路的数据
 * @return {boolean} hasChild 是否包含子节点数据 默认：true
 *
 * */
export function getLinkDataByKey(
  key,
  keyName,
  data,
  hasChild = true,
  children = "child"
) {
  let cloneData = _.cloneDeep(data);
  try {
    //step1 获取当前链路的到所有key集合
    let linKeys = getPathByKey(key, keyName, data, hasChild).map(
      (v) => v[keyName]
    );
    //step 2 过滤数据
    filterData(key, cloneData);

    function filterData(key, data) {
      data.forEach((v, i) => {
        if (!linKeys.includes(v[keyName])) {
          let parentNode = getParentNodeByKey(v[keyName], keyName, cloneData);
          if (!parentNode) {
            cloneData = cloneData.filter((item) =>
              linKeys.includes(item[keyName])
            );
          } else {
            if (parentNode[children]) {
              parentNode[children] = parentNode[children].filter((item) =>
                linKeys.includes(item[keyName])
              );
            }
          }
        }
        if (v.children && Array.isArray(v.children)) {
          filterData(v[keyName], v.children);
        }
      });
    }
    throw cloneData;
  } catch (e) {
    return e;
  }
}

/**
 *
 * @description 根据树中某一节点的key获取该节点所在路径中所有节点结合（最顶层父节点 ==> 当前节点）
 * @author 翟磊
 * @date 2020-03-06
 * @param {string} key - 目标值
 * @param {string} keyName - key名称
 * @param {[tree]} data - 树形数据
 * @return {[json]} 函数返回值:[节点集合]
 *
 * */
export function getPathByKey(
  key,
  keyName,
  data,
  hasChild = false,
  children = "child"
) {
  let tempPathKeys = [];
  try {
    function getNodePath(node) {
      tempPathKeys.push(node);
      if (node[keyName] === key) {
        if (
          hasChild === true &&
          node[children] &&
          Array.isArray(node[children])
        ) {
          let cAllKeys = flatTreeData(node[children]);
          tempPathKeys = [...tempPathKeys, ...cAllKeys];
        } else {
          tempPathKeys = tempPathKeys;
        }
        throw tempPathKeys;
      }
      if (node[children] && node[children].length > 0) {
        for (var i = 0; i < node[children].length; i++) {
          getNodePath(node[children][i]);
        }
        tempPathKeys.pop();
      } else {
        tempPathKeys.pop();
      }
    }
    for (let i = 0; i < data.length; i++) {
      getNodePath(data[i]);
    }
    throw [];
  } catch (e) {
    return e;
  }
}

/**
 *
 * @description 根据key值，查询当前节点数据
 * @author 翟磊
 * @date 2022-03-23
 * @param {string} key - 目标值
 * @param {string} keyName - key名称
 * @param {[tree]} data - 树形数据
 * @return {string | number} 函数返回值:父节点
 *
 * */
export function getNodeByKey(key, keyName, data, children = "child") {
  let node;
  try {
    getData(data);

    function getData(data) {
      data.forEach((v, i) => {
        if (key == v[keyName]) {
          node = v;
          throw v;
        }
        if (v[children] && Array.isArray(v[children])) {
          getData(v[children]);
        }
      });
    }
  } catch (e) {
    return e;
  } finally {
    // !node && console.warn("查无此节点，请检查key值是否正确");
  }
}

/**
 *
 * @description 扁平化tree数据
 * @author 翟磊
 * @date 2022-03-23
 * @param {string} keyName - key名称
 * @param {[tree]} data - 树形数据
 * @return {[string]} 函数返回值:[一维集合]
 *
 * */
export function flatTreeData(data, keyName = "child") {
  let keys = [];
  try {
    getKey(data);
    function getKey(data) {
      data.length > 0 &&
        data.forEach((v) => {
          keys.push(v);
          if (v[keyName] && Array.isArray(v[keyName])) {
            getKey(v[keyName]);
          }
        });
    }
    throw keys;
  } catch (keys) {
    return keys;
  }
}

//校验手机号吗
export function checkPhone(phone = "") {
  var reg = /^[1][3,4,5,7,8,9][0-9]{9}$/;
  return reg.test(phone);
}

/**
 *
 * @description 为节点添加自定义属性
 * @author 翟磊
 * @date 2022-03-23
 * @param {string} key - 目标值-传null，全级添加
 * @param {string} attName - 属性名
 * @param {string} value - 属性值
 * @param {[tree]} data - 树形数据源
 * */
export function addAttributeByKey(
  key,
  attName,
  value = null,
  data,
  children = "child"
) {
  try {
    if (key) {
      let itemNode = getNodeByKey(key, data);
      itemNode[attName] = value || _getUUID(32, 32);
    } else {
      getData(data);
      function getData(data) {
        data.forEach((v) => {
          v[attName] = value || _getUUID(32, 32);
          if (v.hasOwnProperty("disabled")) {
            v.disabled = v.disabled == 0 ? false : true;
          }
          if (v[children] && Array.isArray(v[children])) {
            getData(v[children]);
          }
        });
      }
    }
    throw data;
  } catch (e) {
    return e;
  }
}

export function debounce(func, delay = 500) {
  var timer = null;
  return function () {
    var context = this;
    var args = arguments;
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(function () {
      func.apply(context, args);
      timer = null;
    }, delay);
  };
}


/**
 *
 * @description 根据key值，查询父节点，返回父节点数据
 * @author 翟磊
 * @date 2020-03-06
 * @param {string} key - 目标值
 * @param {string} keyName - key名称
 * @param {[tree]} data - 树形数据
 * @return {string | number} 函数返回值:父节点
 *
 * */
 export function getParentNodeByKey(key, keyName, data,child="child") {
    let parentData = null,
      hasFlag = false;
    try {
      getKey(keyName, data);
  
      function getKey(keyName, data, parent) {
        data.forEach((v, i) => {
          parentData = parent;
          if (v[keyName] == key) {
            hasFlag = true;
            throw parentData;
          }
          if (v[child] && Array.isArray(v[child])) {
            getKey(keyName, v[child], v);
          }
        });
      }
    } catch (e) {
      return e;
    }
  }